<?php

namespace app\common\service;

use app\common\model\RuinuoVerify;
use think\facade\Cache;
use think\facade\Db;

class Validate
{

    public function Rule($verify = [], $params = [], $id = 0)
    {
        $Validate = $this->VerifyData();
        foreach ($verify as $k => $v) {
            $value = isset($params[$v['field']]) ? $params[$v['field']] : '';
            $rule = !empty($Validate[$v['rule']]) ? $Validate[$v['rule']] : '';
            $title = !empty($rule['title']) ? $rule['title'] : '';
            $need = 1;
            switch ($v['type']) {
                case "json":
                    $need = 2;
                    $value = !empty($params[$v['path']]) ? json_decode($params[$v['path']], true) : [];
                    $check = $this->JsonCheck($value, $v, $rule);
                    if ($check['code'] == 203) {
                        return $check;
                    }
                    break;
                case "event":
                    $need = $this->GetEvent($params, $v);
                    break;
            }
            if ($need == 1) {
                switch ($v['rule']) {
                    case "only":
                        $check = $this->OnlyCheck($value, $v, $id);
                        $title = "不能重复";
                        break;
                    default:
                        $tag = !empty($v['tag']) ? $v['tag'] : '';
                        if ($tag == 'password' && $v['rule'] == 'required' && !empty($id)) {
                            $check = true;
                        } else {
                            $check = $this->VerifyCheck($value, $v['rule'], $rule);
                        }


                }
                if (empty($check)) {
                    $BackData = ['field' => $v['field']];
                    return ['code' => 203, 'msg' => $v['title'] . $title, 'data' => $BackData];
                }
            }
        }
        return ['code' => 200];
    }


    /*唯一值验证*/
    public function OnlyCheck($value = '', $item = [], $id = 0)
    {
        $database = $item['table'];
        $where = "" . $item['field'] . "='" . $value . "'";
        if ($item['key_table'] != $item['table']) {
            if ($id) {
                $find = Db::name($item['key_table'])->where("id='" . $id . "'")->find();
                if ($item['type'] == 1) {
                    $where .= " and " . $item['sub_field'] . "!='" . $find[$item['key_field']] . "'";//正向关联
                } else {
                    $where .= " and " . $item['key_field'] . "!='" . $find[$item['sub_field']] . "'";;//反向关联
                }
            }
        } else {
            if ($id) {
                $where .= " and id!='" . $id . "'";
            }
        }
        $count = Db::name($database)->where($where)->count();
        if ($count >= 1) {
            return false;
        }
        return true;

    }

    /*Json数据验证*/
    public function JsonCheck($rows = [], $items=[], $validate=[])
    {
        $field = $items['field'];
        $title = $items['title'];
        foreach ($rows as $k => $v) {
            $BackData = ['field' => $items['path'] . '||' . $items['field'] . '||' . $k];
            $value = isset($v[$field]) ? $v[$field] : '';

            $check = $this->VerifyCheck($value, $items['rule'], $validate);
            if (!$check) {
                return ['code' => 203, 'msg' => $title . $validate['title'], 'data' => $BackData];
            }
        }
        return ['code' => 200];
    }

    /*自定义规则验证数据*/
    public function VerifyData()
    {
        $CacheId = 'ruinuo_verify';
        if (Cache::get($CacheId)) {
            $Rule = Cache::get($CacheId);
        } else {
            $RuinuoVerify = new RuinuoVerify();
            $Verify = $RuinuoVerify->field("name,num,guize")->select()->toArray();
            $Rule = [];
            foreach ($Verify as $k => $v) {
                $Rule[strtolower($v['num'])] = [
                    'title' => $v['name'],
                    'rule' => $v['guize'],
                ];
            }
            $Rule['required'] = [
                'title' => '必填',
                'rule' => '/\S+/',
            ];
            Cache::set($CacheId, $Rule, 600);
        }
        return $Rule;
    }

    /*自定义规则验证*/
    public function VerifyCheck($value, $rule, $validate = [])
    {
        if ($value == '' && $rule != 'required') {
            return true;
        }
        if ($value == '' && $rule == 'required') {
            return false;
        }


        if (isset($validate['rule'])) {
            $rule = $validate['rule'];
            if (preg_match($rule, $value)) {
                return true;
            } else {
                return false;
            }
        }
        return true;
    }

    public function GetEvent($params = [], $v = [])
    {
        $need = 2;
        $val = isset($params[$v['event_field']]) ? $params[$v['event_field']] : '';
        $event_val = $v['event_val'];
        $event_vals = explode(',', $event_val);
        switch ($v['event_type']) {
            case ">":
                if ($val > $event_val) {
                    $need = 1;
                }
                break;
            case "<":
                if ($val < $event_val) {
                    $need = 1;
                }
                break;
            case "=":
                if ($val == $event_val) {
                    $need = 1;
                }
                break;
            case "!=":
                if ($val != $event_val) {
                    $need = 1;
                }
                break;
            case ">=":
                if ($val >= $event_val) {
                    $need = 1;
                }
                break;
            case "<=":
                if ($val <= $event_val) {
                    $need = 1;
                }
                break;
            case "in":
                foreach ($event_vals as $k2 => $v2) {
                    if ($v2 == $val) {
                        $need = 1;
                    }
                }
                break;
            case "notin":
                $need = 1;
                foreach ($event_vals as $k2 => $v2) {
                    if ($v2 == $val) {
                        $need = 2;
                    }
                }
                break;
        }
        return $need;
    }
}